package com.milhouz.bomberrokon.texture;

import java.util.Map.Entry;

import com.milhouz.bomberrokon.model.MapModel;
import com.milhouz.bomberrokon.model.TileData;
import com.stickycoding.Rokon.Texture;
import com.stickycoding.Rokon.TextureAtlas;
import com.stickycoding.Rokon.TextureManager;

public class TextureLoader {

	private final int TEXTURE_ATLAS_WIDTH = 512;
	private final int TEXTURE_ATLAS_HEIGHT = 1024;

	private static TextureLoader instance;

	public static TextureLoader getInstance() {
		if (instance == null) {
			instance = new TextureLoader();
		}
		return instance;
	}

	// --- Textures
	private TextureAtlas mAtlas2;
	private TextureAtlas mAtlas1;
	private Texture[] mBomberTextures;
	private Texture[] mMapTextures;
	private Texture mBombTextures;
	private Texture[] mExplosionTextures = new Texture[9];
	private Texture[] mItemsTextures = new Texture[3];
	private Texture[] mHudTextures = new Texture[3];
	private Texture mBackgroundTexture;

	private void clearTextures() {
		mAtlas2 = null;
		mAtlas1 = null;
		mBomberTextures = null;
		mMapTextures = null;
		mBombTextures = null;
		mExplosionTextures = new Texture[9];
		mItemsTextures = new Texture[3];
		mHudTextures = new Texture[3];
		mBackgroundTexture = null;
	}

	public void init(final MapModel mapModel, final String[] bombers) {
		clearTextures();
		int tileSize = mapModel.getTileSize();
		String tilePath = tileSize + "x" + tileSize;
		// Initialize Texture Atlas
		mAtlas1 = new TextureAtlas(TEXTURE_ATLAS_WIDTH, TEXTURE_ATLAS_HEIGHT);
		mAtlas2 = new TextureAtlas(TEXTURE_ATLAS_WIDTH, TEXTURE_ATLAS_HEIGHT);
		// -- Added in Atlas 1
		// Load background texture
		loadBackgroundTexture(mapModel);
		// Load items
		loadItemTextures(tilePath);
		// Load Hud textures
		loadHudTextures();
		// -- Added in Atlas 2
		// Load Map textures following MapModel
		loadMapTextures(mapModel);
		// Load Bomb animation textures
		loadBombTextures(tileSize, tilePath);
		// Load Bomber textures and animations
		loadBombersTextures(bombers, tilePath);
		// Load Explosions animation textures
		loadExplosionTextures(tileSize, tilePath);
		// Load atlas to TextureManager
		TextureManager.load(mAtlas1);
		TextureManager.load(mAtlas2);
	}

	/** Load Bomberman textures and animations */
	private void loadBombersTextures(final String[] bombers, final String tilePath) {
		mBomberTextures = new Texture[bombers.length];
		for (int i = 0; i < bombers.length; i++) {
			mAtlas2.insert(mBomberTextures[i] = new Texture("img/" + tilePath + "/BombersOld/emo_im_happy.png"));
		}
	}

	/** Load Bomb animation textures */
	private void loadBombTextures(final int tileSize, final String tilePath) {
		mAtlas2.insert(mBombTextures = new Texture("img/" + tilePath + "/Bombs/bomb.png"));
		mBombTextures.setTileSize(tileSize, tileSize);
	}

	/** Load Explosions animation textures */
	private void loadExplosionTextures(final int tileSize, final String tilePath) {
		mAtlas2.insert(mExplosionTextures[0] = new Texture("img/" + tilePath + "/Explosion/up.png"));
		mExplosionTextures[0].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[1] = new Texture("img/" + tilePath + "/Explosion/upExt.png"));
		mExplosionTextures[1].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[2] = new Texture("img/" + tilePath + "/Explosion/down.png"));
		mExplosionTextures[2].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[3] = new Texture("img/" + tilePath + "/Explosion/downExt.png"));
		mExplosionTextures[3].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[4] = new Texture("img/" + tilePath + "/Explosion/left.png"));
		mExplosionTextures[4].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[5] = new Texture("img/" + tilePath + "/Explosion/leftExt.png"));
		mExplosionTextures[5].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[6] = new Texture("img/" + tilePath + "/Explosion/right.png"));
		mExplosionTextures[6].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[7] = new Texture("img/" + tilePath + "/Explosion/rightExt.png"));
		mExplosionTextures[7].setTileSize(tileSize, tileSize);
		mAtlas2.insert(mExplosionTextures[8] = new Texture("img/" + tilePath + "/Explosion/center.png"));
		mExplosionTextures[8].setTileSize(tileSize, tileSize);
	}

	/** Load Hud textures */
	private void loadHudTextures() {
		mAtlas1.insert(mHudTextures[0] = new Texture("img/menu/hud.png"));
		mAtlas1.insert(mHudTextures[1] = new Texture("img/menu/numbers.png"));
		mHudTextures[1].setTileSize(19, 20);
		mAtlas1.insert(mHudTextures[2] = new Texture("img/menu/hud_timer.png"));
	}

	/** Load Map textures following MapModel */
	private void loadMapTextures(final MapModel mapModel) {
		mMapTextures = new Texture[mapModel.getTileData().size() + 1];
		// Map tile textures
		for (Entry<Integer, TileData> texEntry : mapModel.getTileData().entrySet()) {
			mAtlas2.insert(mMapTextures[texEntry.getKey()] = new Texture("maps/" + mapModel.getMapCode() + "/img/"
					+ texEntry.getValue().getTexFilename()));
		}
		// Wall explosion animation
		mAtlas2.insert(mMapTextures[mapModel.getTileData().size()] = new Texture("maps/" + mapModel.getMapCode() + "/img/"
				+ mapModel.getExploseWallFile()));
		mMapTextures[mapModel.getTileData().size()].setTileSize(mapModel.getTileSize(), mapModel.getTileSize());
	}

	/** Load items */
	private void loadItemTextures(String tilePath) {
		mAtlas1.insert(mItemsTextures[0] = new Texture("img/" + tilePath + "/Item/Flame.png"));
		mAtlas1.insert(mItemsTextures[1] = new Texture("img/" + tilePath + "/Item/Bomb.png"));
		mAtlas1.insert(mItemsTextures[2] = new Texture("img/" + tilePath + "/Item/Speed.png"));
	}

	/** Load background texture in a separated atlas */
	private void loadBackgroundTexture(final MapModel mapModel) {
		if (mapModel.getBackgroundFile() != null) {
			mAtlas1.insert(mBackgroundTexture = new Texture("maps/" + mapModel.getMapCode() + "/img/" + mapModel.getBackgroundFile()));
		}
	}

	public TextureAtlas getAtlas() {
		return mAtlas2;
	}

	public Texture[] getBomberTextures() {
		return mBomberTextures;
	}

	public Texture getBomberTextures(int idBomber) {
		return mBomberTextures[idBomber];
	}

	public Texture[] getMapTextures() {
		return mMapTextures;
	}

	public Texture getBombTextures() {
		return mBombTextures;
	}

	public Texture[] getExplosionTextures() {
		return mExplosionTextures;
	}

	public Texture getItemsTextures(int idItem) {
		return mItemsTextures[idItem];
	}

	public Texture[] getHudTextures() {
		return mHudTextures;
	}

	public Texture getBackgroundTexture() {
		return mBackgroundTexture;
	}

}
